#include "ftp_client.h"
#include <iostream>
#include <string>

void FtpClient::globalInit() {
    curl_global_init(CURL_GLOBAL_DEFAULT);
}
void FtpClient::globalCleanup() {
    curl_global_cleanup();
}

FtpClient::FtpClient(const std::string& user, const std::string& pass)
    : m_user(user), m_pass(pass) {}

FtpClient::~FtpClient() {}

CURL* FtpClient::createUploadSessionWithFILE(const std::string& url, FILE* filePtr, long fileSize) {
    if (!filePtr) return nullptr;
    CURL* curl = curl_easy_init();
    if (!curl) return nullptr;

    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
    curl_easy_setopt(curl, CURLOPT_READDATA, filePtr);
    curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, static_cast<curl_off_t>(fileSize));

    if (!m_user.empty() || !m_pass.empty()) {
        std::string up = m_user + ":" + m_pass;
        curl_easy_setopt(curl, CURLOPT_USERPWD, up.c_str());
    }

    curl_easy_setopt(curl, CURLOPT_FTP_CREATE_MISSING_DIRS, CURLFTP_CREATE_DIR);
    curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 15L);
    curl_easy_setopt(curl, CURLOPT_FTP_RESPONSE_TIMEOUT, 30L);

    // Note: not enabling CURLOPT_VERBOSE here; enable in caller when debugging.
    return curl;
}

bool FtpClient::createRemoteDir(const std::string& dirUrl) {
    if (dirUrl.empty()) return false;
    std::string folderUrl = dirUrl;
    if (folderUrl.back() != '/') folderUrl += '/';
    const std::string dummyName = ".curl_mkdir_dummy.tmp";
    const std::string dummyUrl = folderUrl + dummyName;

    CURL* curl = curl_easy_init();
    if (!curl) return false;

    if (!m_user.empty() || !m_pass.empty()) {
        std::string up = m_user + ":" + m_pass;
        curl_easy_setopt(curl, CURLOPT_USERPWD, up.c_str());
    }

    // Upload 0-byte dummy to trigger directory creation
    curl_easy_setopt(curl, CURLOPT_URL, dummyUrl.c_str());
    curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
    curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)0);
    curl_easy_setopt(curl, CURLOPT_READFUNCTION, [](char*, size_t, size_t, void*) -> size_t { return 0; });
    curl_easy_setopt(curl, CURLOPT_FTP_CREATE_MISSING_DIRS, CURLFTP_CREATE_DIR);
    curl_easy_setopt(curl, CURLOPT_NOBODY, 0L);

    CURLcode res = curl_easy_perform(curl);
    if (res != CURLE_OK) {
        std::cerr << "[ftp_client] createRemoteDir: dummy upload failed: " << curl_easy_strerror(res) << std::endl;
        // continue best-effort
    }

    // Try to delete dummy file (best-effort)
    struct curl_slist* quote = nullptr;
    std::string deleCmd = "DELE " + dummyName;
    quote = curl_slist_append(quote, deleCmd.c_str());
    curl_easy_setopt(curl, CURLOPT_URL, dummyUrl.c_str()); // ensure same context
    curl_easy_setopt(curl, CURLOPT_NOBODY, 1L);
    curl_easy_setopt(curl, CURLOPT_QUOTE, quote);
    res = curl_easy_perform(curl);
    if (res != CURLE_OK) {
        std::cerr << "[ftp_client] createRemoteDir: dummy delete (warning): " << curl_easy_strerror(res) << std::endl;
    }
    curl_slist_free_all(quote);
    curl_easy_cleanup(curl);
    return true;
}
